﻿using System;
using System.Linq;
using EPiAbstractions.Community.Blog;
using EPiServer.Common.Sorting;
using EPiServer.Community.Blog;
using JoelAbrahamsson.TestUtilities;
using Moq;
using StructureMap.AutoMocking;
using Xunit;

namespace JoelAbrahamsson.MetaWeblog.Tests
{
    public class GetRecentPostsTests
    {
        [Fact]
        public void GivenBlogIDAndCredentials_GetRecentPosts_ValidatesUser()
        {
            int blogID = 1;
            string username = RandomValues.String;
            string password = RandomValues.String;
            Mock<Blog> fakeBlog = new Mock<Blog>();
            fakeBlog.Setup(blog => blog.ID).Returns(blogID);
            MoqAutoMocker<MetaWeblogHandler> metaWebLogHandlerAutoMocker = new MoqAutoMocker<MetaWeblogHandler>();
            metaWebLogHandlerAutoMocker.PartialMockTheClassUnderTest();
            Mock<MetaWeblogHandler> fakeMetaWebLogHandler = Mock.Get(metaWebLogHandlerAutoMocker.ClassUnderTest);
            fakeMetaWebLogHandler.Setup(handler => handler.GetValidatedUser(It.IsAny<Blog>(), It.IsAny<string>(), It.IsAny<string>()));
            fakeMetaWebLogHandler.Setup(handler => handler.GetBlog(blogID.ToString())).Returns(fakeBlog.Object);

            metaWebLogHandlerAutoMocker.ClassUnderTest.GetRecentPosts(blogID.ToString(), username, password, 10);

            Mock.Get(metaWebLogHandlerAutoMocker.ClassUnderTest).Verify(handler => handler.GetValidatedUser(fakeBlog.Object, username, password));
        }

        [Fact]
        public void GivenBlogID_GetRecentPosts_ReturnsCorrectNumberOfLatestPostsInBlogFromBlogHandler()
        {
            int blogID = 1;
            string username = RandomValues.String;
            string password = RandomValues.String;
            Mock<Blog> fakeBlog = new Mock<Blog>();
            fakeBlog.Setup(blog => blog.ID).Returns(blogID);
            MoqAutoMocker<MetaWeblogHandler> metaWebLogHandlerAutoMocker = new MoqAutoMocker<MetaWeblogHandler>();
            metaWebLogHandlerAutoMocker.PartialMockTheClassUnderTest();
            Mock<MetaWeblogHandler> fakeMetaWebLogHandler = Mock.Get(metaWebLogHandlerAutoMocker.ClassUnderTest);
            fakeMetaWebLogHandler.Setup(handler => handler.GetValidatedUser(It.IsAny<Blog>(), It.IsAny<string>(), It.IsAny<string>()));
            fakeMetaWebLogHandler.Setup(handler => handler.GetBlog(blogID.ToString())).Returns(fakeBlog.Object);
            fakeMetaWebLogHandler.Setup(handler => handler.GetEntryCategories(It.IsAny<Entry>()));
            fakeMetaWebLogHandler.Setup(handler => handler.GetEntryTags(It.IsAny<Entry>()));
            Mock<Entry> fakeEntryToReturn = new Mock<Entry>();
            fakeEntryToReturn.Setup(entry => entry.ID).Returns(1);
            EntryCollection recentEntries = new EntryCollection { fakeEntryToReturn.Object };

            Mock<IBlogHandlerFacade> fakeBlogHandlerFacade = Mock.Get(metaWebLogHandlerAutoMocker.Get<IBlogHandlerFacade>());
            fakeBlogHandlerFacade.Setup(
                handler => handler.GetEntries(It.IsAny<Blog>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<EntrySortOrder[]>())).Returns(recentEntries);

            Post[] returnedPosts = metaWebLogHandlerAutoMocker.ClassUnderTest.GetRecentPosts(blogID.ToString(), username, password, 10);

            fakeBlogHandlerFacade.Verify(handler => handler.GetEntries(fakeBlog.Object, 1, 10, It.Is<EntrySortOrder[]>(
                sortOrders =>
                        sortOrders[0].Field == EntrySortField.LastUpdate && sortOrders[0].Direction == SortingDirection.Descending)));
            foreach (Entry entry in recentEntries)
            {
                bool returnedPostArrayContainsEntry = returnedPosts.Count(post => post.postid.ToString() == entry.ID.ToString()) == 1;
                Assert.True(returnedPostArrayContainsEntry);
            }
        }
    }
}
